package org.liaohailong.library.image

import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import java.io.Closeable
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.lang.ref.WeakReference

import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/**
 * Author: liaohailong
 * Date: 2019/3/8
 * Time: 11:13 AM
 * Description: 图片操作工具类
 **/
object ImageHelper {
    private val CPU_COUNT = Runtime.getRuntime().availableProcessors()
    private val CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4))
    private val EXECUTOR: ExecutorService = Executors.newFixedThreadPool(CORE_POOL_SIZE)
    private val MAIN_HANDLER = Handler(Looper.getMainLooper())

    fun saveBitmapAsync(bitmap: Bitmap, path: String, onImageHelperCallback: OnImageHelperCallback?) {
        val saveRunnable = Runnable {
            val weakCallback = WeakReference(onImageHelperCallback)
            val success = saveBitmapSync(bitmap, path)
            MAIN_HANDLER.post {
                weakCallback.get()?.onSavedComplete(success, path)
            }
        }
        EXECUTOR.execute(saveRunnable)
    }

    fun copyFileAsync(originPath: String, targetPath: String, onImageHelperCallback: OnImageHelperCallback?) {
        val saveRunnable = Runnable {
            val weakCallback = WeakReference(onImageHelperCallback)
            val success = copyFileSync(originPath, targetPath)
            MAIN_HANDLER.post {
                weakCallback.get()?.onSavedComplete(success, targetPath)
            }
        }
        EXECUTOR.execute(saveRunnable)
    }

    fun saveBitmapSync(bitmap: Bitmap, path: String): Boolean {
        val file = File(path)
        if (file.exists()) return false

        var fos: FileOutputStream? = null
        return try {
            fos = FileOutputStream(File(path))
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
        } catch (e: java.lang.Exception) {
            false
        } finally {
            closeIO(fos)
        }
    }

    fun copyFileSync(originPath: String, targetPath: String): Boolean {
        val originFile = File(originPath)
        if (!originFile.exists()) return false

        val targetFile = File(targetPath)
        if (targetFile.exists()) return false
        if (!targetFile.createNewFile()) return false

        var fis: FileInputStream? = null
        var fos: FileOutputStream? = null
        return try {
            fis = FileInputStream(originFile)
            fos = FileOutputStream(targetFile)

            val fisChannel = fis.channel
            val fosChannel = fos.channel

            fosChannel.transferFrom(fisChannel, 0, fisChannel.size())
            true
        } catch (e: Exception) {
            false
        } finally {
            closeIO(fis)
            closeIO(fos)
        }
    }

    private fun closeIO(closeable: Closeable?) {
        try {
            closeable?.close()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    interface OnImageHelperCallback {
        fun onSavedComplete(success: Boolean, path: String)
    }
}